package com.cwz.file.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cwz.api.entity.UserFile;
import com.cwz.api.entity.UserPath;
import com.cwz.core.result.R;
import com.cwz.core.utils.string.StringUtils;
import com.cwz.file.mapper.UserFileMapper;
import com.cwz.file.mapper.UserPathMapper;
import com.cwz.file.model.UserPathVo;
import com.cwz.file.service.UserPathService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * <p>
 * 用户文件目录表 服务实现类
 * </p>
 *
 * @author Wen
 * @since 2023-06-28
 */
@Service
public class UserPathServiceImpl extends ServiceImpl<UserPathMapper, UserPath> implements UserPathService {
	@Autowired
	private UserPathMapper userPathMapper;
	@Autowired
	private UserFileMapper userFileMapper;
	@Resource
	private DataSourceTransactionManager transactionManager;

	@Override
	public R<Void> addUserPath(UserPath userPath) {
		TransactionStatus status = getTransactionStatus("addUserPath", TransactionDefinition.PROPAGATION_REQUIRED, TransactionDefinition.ISOLATION_DEFAULT);
		try {
			if (this.userPathMapper.insert(userPath) > 0) {
				// 如果是子节点要把上级变父节点
				if (userPath.getPid() != 0) {
					UserPath selectById = this.userPathMapper.selectById(userPath.getPid());
					if (selectById.getIsParent().equals("0")) {
						UserPath updPath = new UserPath();
						updPath.setPathId(userPath.getPid());
						updPath.setIsParent("1");
						this.userPathMapper.updateById(updPath);
					}
				}
				// 提交事务
				transactionManager.commit(status);
				return R.ok("新建文件夹成功");
			}
		} catch (Exception e) {
			e.printStackTrace();
			// 回滚事务
			transactionManager.rollback(status);
		}
		return R.fail("新建文件夹失败");
	}

	@Override
	public R<Void> updateUserPath(UserPath userPath) {
		if (this.userPathMapper.updateById(userPath) > 0) {
			return R.ok("编辑文件夹成功");
		}
 		return R.fail("编辑文件夹失败");
	}

	@Override
	public R<Void> deleteUserPath(Long pathId) {
		TransactionStatus status = getTransactionStatus("deleteUserPath", TransactionDefinition.PROPAGATION_REQUIRED, TransactionDefinition.ISOLATION_DEFAULT);
		try {
			UserPath userPath = this.userPathMapper.selectById(pathId);
			if (userPath.getIsParent().equals("1")) {
				return R.ok("该文件夹下存在子文件夹，不能删除文件夹");
			}
			if (this.userFileMapper.selectCount(new QueryWrapper<UserFile>().eq("path_id", pathId)) > 0) {
				return R.ok("该目录下存在文件，不能删除文件夹");
			}
			if (this.userPathMapper.deleteById(pathId) > 0) {
				// 判断他上级节点是否还有子节点，没有就设为非父节点
				if (this.userPathMapper.selectCount(new QueryWrapper<UserPath>().eq("pid", userPath.getPid())) == 0) {
					UserPath updPath = new UserPath();
					updPath.setPathId(userPath.getPid());
					updPath.setIsParent("0");
					this.userPathMapper.updateById(updPath);
				}
				// 提交事务
				transactionManager.commit(status);
				return R.ok("删除文件夹成功");
			}
		} catch (Exception e) {
			e.printStackTrace();
			// 回滚事务
			transactionManager.rollback(status);
		}
		return R.fail("删除文件夹失败");
	}

	@Override
	public R<List<UserPathVo>> listUserPath(Long userId) {
		List<UserPath> userPaths = this.userPathMapper.selectList(new QueryWrapper<UserPath>()
			.eq("user_id", userId)
			.orderByAsc("path_id"));
		List<UserPathVo> result = new ArrayList<>();
		for (Iterator<UserPath> iterator = userPaths.iterator(); iterator.hasNext(); ) {
			UserPath userPath = iterator.next();
			if (userPath.getPid() == 0) {
				UserPathVo userPathVo = new UserPathVo();
				BeanUtils.copyProperties(userPath, userPathVo);
				result.add(userPathVo);
				iterator.remove();
			}
		}
		this.getCatalogue(result, userPaths);
		return R.ok(result);
	}

	private void getCatalogue(List<UserPathVo> result, List<UserPath> userPaths) {
		if (StringUtils.isEmpty(result) || StringUtils.isEmpty(userPaths)) return;
		for (UserPathVo item : result) {
			for (Iterator<UserPath> iterator = userPaths.iterator(); iterator.hasNext(); ) {
				UserPath userPath = iterator.next();
				if (userPath.getPid().equals(item.getPathId())) {
					UserPathVo userPathVo = new UserPathVo();
					BeanUtils.copyProperties(userPath, userPathVo);
					if (StringUtils.isNull(item.getChildren())) item.setChildren(new ArrayList<>());
					item.getChildren().add(userPathVo);
					iterator.remove();
				}
			}
			this.getCatalogue(item.getChildren(), userPaths);
		}
	}

	/**
	 * @Description: 开启事务
	 * @Author: Wen
	 * @param name: 					事务名称
	 * @param propagationBehavior: 		事务传播行为
	 * @param isolationLevel:  			事务隔离级别
	 * @return: org.springframework.transaction.TransactionStatus
	 **/
	private TransactionStatus getTransactionStatus(String name, int propagationBehavior, int isolationLevel) {
		// 开启事务
		DefaultTransactionDefinition def = new DefaultTransactionDefinition();
		def.setName(name);
		def.setPropagationBehavior(propagationBehavior);
		def.setIsolationLevel(isolationLevel);
		return transactionManager.getTransaction(def);
	}
}
